package gui;

import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.JViewport;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;

import brac.Bisection;

import fn.Constant;
import fn.Function;
import fn.Global;
import fn.Multiply;
import fn.Sine;
import fn.Subtract;
import fn.Variable;

public class OutputTable extends JTable {
	private static final long serialVersionUID = -6305991550206178263L;

	int _interval = 750;
	boolean _loops = false;
	private JTable t = this;

	private Timer tPlay = new Timer(_interval, new ActionListener() {
		public void actionPerformed(ActionEvent e) {
			try {
				if (_loops)
					t.getSelectionModel().setSelectionInterval(y = (y + 1) % t.getRowCount(), y);
				else if (y < t.getRowCount() - 1) {
					t.getSelectionModel().setSelectionInterval(++y, y);
					try {
						if (y == t.getRowCount() - 1)
							getParent().getParent().getParent().repaint();
					} catch (Exception ex) {}
				}
			} catch (Exception e2) {}
		}
	});

	private int y = -1;
	private int from, to;

	public OutputTable(final PlotCanvas plot) {
		this.setFillsViewportHeight(true);
		this.setSize(700, 200);
		this.setBounds(50, 100, 200, 200);
		getSelectionModel().addListSelectionListener(new ListSelectionListener() {

			@Override
			public void valueChanged(ListSelectionEvent arg0) {
				try {
					y = t.getSelectionModel().getMinSelectionIndex();
					if (plot != null) {
						plot.removePointAll();
						for (int x = from; x <= to; x++)
							plot.addPoint(new Point((Double) getValueAt(y, x), Double.NaN), PlotCanvas.TYPE_X);
					}
					properScroll();
				} catch (Exception e) {}
			}

		});
	}

	@Override
	public boolean isCellEditable(int paramInt1, int paramInt2) {
		return false;
	}

	private void properScroll() {
		if (!(getParent() instanceof JViewport))
			return;
		JViewport viewport = (JViewport) getParent();
		Rectangle rect = getCellRect(getSelectedRow(), getSelectedColumn(), true);
		java.awt.Point pt = viewport.getViewPosition();
		rect.setLocation(rect.x - pt.x, rect.y - pt.y);
		viewport.scrollRectToVisible(rect);
	}

	public void init(String[] header, ArrayList<Double>[] values, int[] headerLimits) {
		try {
			from = headerLimits[0];
			to = headerLimits[1];
			if (header != null)
				for (int i = 0; i < header.length; i++) {
					String st[] = new String[values[i].size()];
					Iterator<Double> itn = values[i].iterator();
					int j = 0;
					while (itn.hasNext())
						st[j++] = itn.next() + "";
					((DefaultTableModel) getModel()).addColumn(header[i], st);
				}
		} catch (Exception e) {}
	}

	@Override
	public Object getValueAt(int row, int column) {
		if (super.getValueAt(row, column) == null)
			return "";
		return Global.tol(Double.parseDouble((String) super.getValueAt(row, column)));
	}

	public void play() {
		tPlay.setDelay(_interval);
		tPlay.restart();
	}

	public void pause() {
		tPlay.stop();
	}

	public void stop() {
		getSelectionModel().setSelectionInterval(0, 0);
		y = -1;
		tPlay.stop();
	}

	public static void main(String[] args) throws Exception {
		UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		Function fn = Subtract.create(Multiply.create(Variable.create(), Sine.create(Variable.create())), Constant.create(1));
		Bisection b = new Bisection();
		b.solve(fn, 0.0012166, 50, 0, 2);
		//
		OutputTable t = new OutputTable(null);
		t.init(b.header(), b.values(), b.fromTo());
		t.play();
		JFrame f = new JFrame();
		f.add(t);
		f.pack();
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setVisible(true);
	}

}
